﻿using Microsoft.AspNetCore.Mvc;
using LPP.Service.Payment;
using static LPP.Service.Payment.TenPayV3;
using LPP.Core.WeChat;
using System.Text;
using LPP.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace LPP.API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class WeChatPayController : ControllerBase
    {
        private readonly IConfiguration _config;
        private readonly SqlDbContext _dbContext;

        public WeChatPayController(IConfiguration config, SqlDbContext dbContext)
        {
            _config = config;
            _dbContext = dbContext; 
        }

        [HttpGet("Orders/{orderId}/status")]
        public async Task<IActionResult> GetOrderStatus(string orderId)
        {
            try
            {
                var order = await _dbContext.Orders.FirstOrDefaultAsync(o => o.OrderID == orderId);

                if (order == null)
                {
                    return NotFound(new { success = false, message = "订单不存在" });
                }

                return Ok(new
                {
                    success = true,
                    isPaid = order.Status == (OrderStatus)2,
                    status = order.Status,
                    paidAt = order.PaidAt
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"查询订单状态失败: {ex.Message}");
                return StatusCode(500, new { success = false, message = "查询订单状态失败" });
            }
        }
        [HttpPost("PrePay")]
        public async Task<IActionResult> CreatePrePay([FromBody] OrderRequest request)
        {
            // Step 1: 微信支付的必要参数
            string appId = _config["WeChat:AppId"];
            string mchId = _config["WeChat:MchId"];
            string apiKey = _config["WeChat:APIKey"]; // 统一为 APIKey
            string notifyUrl = _config["WeChat:NotifyUrl"];

            string nonceStr = Guid.NewGuid().ToString("N").Substring(0, 32);
            string outTradeNo = request.OrderId;
            int totalFee = (int)(request.Amount * 100); // 转换为分
            string ip = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "127.0.0.1";

            // Step 2: 拼接统一下单请求参数
            var parameters = new SortedDictionary<string, string>
            {
                { "appid", appId },
                { "mch_id", mchId },
                { "nonce_str", nonceStr },
                { "body", request.Description },
                { "out_trade_no", outTradeNo },
                { "total_fee", totalFee.ToString() },
                { "spbill_create_ip", ip },
                { "notify_url", notifyUrl },
                { "trade_type", "JSAPI" },
                { "openid", request.OpenId } // 需要在前端传递 OpenId
            };

            // Step 3: 生成签名
            string sign = WeChatHelper.GenerateSign(parameters, apiKey);
            parameters.Add("sign", sign);

            // Step 4: 调用微信支付统一下单接口
            string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            string xmlRequest = WeChatHelper.ToXml(parameters);

            using var httpClient = new HttpClient();
            var content = new StringContent(xmlRequest, Encoding.UTF8, "application/xml");
            var response = await httpClient.PostAsync(url, content);
            string result = await response.Content.ReadAsStringAsync();

            // Step 5: 解析微信返回结果
            var responseParams = WeChatHelper.FromXml(result);
            if (responseParams["return_code"] == "SUCCESS" && responseParams["result_code"] == "SUCCESS")
            {
                // 返回前端需要的支付参数
                var paymentParams = new
                {
                    timeStamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(),
                    nonceStr = responseParams["nonce_str"],
                    package = $"prepay_id={responseParams["prepay_id"]}",
                    signType = "MD5",
                    paySign = WeChatHelper.GenerateSign(new SortedDictionary<string, string>
                    {
                        { "appId", appId },
                        { "timeStamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString() },
                        { "nonceStr", responseParams["nonce_str"] },
                        { "package", $"prepay_id={responseParams["prepay_id"]}" },
                        { "signType", "MD5" }
                    }, apiKey)
                };

                return Ok(new { success = true, paymentParams });
            }

            return BadRequest(new { success = false, message = responseParams["return_msg"] });
        }

        [HttpPost("Notify")]
        public IActionResult Notify([FromBody] string xmlData)

        {
            if (string.IsNullOrEmpty(xmlData))
            {
                return Content("<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[Empty XML data]]></return_msg></xml>", "application/xml");
            }

            Console.WriteLine($"Received XML: {xmlData}");
            var parameters = WeChatHelper.FromXml(xmlData);
            string apiKey = _config["WeChat:APIKey"];

            // 验证签名
            if (WeChatHelper.VerifySign(parameters, apiKey))
            {
                // 支付成功
                if (parameters["return_code"] == "SUCCESS" && parameters["result_code"] == "SUCCESS")
                {
                    string outTradeNo = parameters["out_trade_no"];
                    // 检查订单是否已处理（幂等性）
                    if (!OrderAlreadyProcessed(outTradeNo))
                    {
                        // 更新订单状态为已支付
                        UpdateOrderStatus(outTradeNo);
                    }

                    return Content("<xml><return_code>SUCCESS</return_code></xml>", "application/xml");
                }
            }

            return Content("<xml><return_code>FAIL</return_code></xml>", "application/xml");
        }

        private bool OrderAlreadyProcessed(string orderId)
        {
            try
            {
                var order = _dbContext.Orders.FirstOrDefault(o => o.OrderID == orderId);

                if (order == null)
                {
                    return false;
                }

                return order.Status == (OrderStatus)2; // 假设 "2" 是已支付状态
            }
            catch (Exception ex)
            {
                // 记录错误日志
                Console.WriteLine($"检查订单是否已处理时出错: {ex.Message}");
                throw;
            }
        }

        private void UpdateOrderStatus(string orderId)
        {
            // 更新订单状态为已支付的逻辑
            try
            {
                var order = _dbContext.Orders.FirstOrDefault(o => o.OrderID == orderId);

                if (order == null)
                {
                    throw new Exception($"订单 ID: {orderId} 不存在");
                }

                order.Status = (OrderStatus)2; // 更新为已支付状态
                order.PaidAt = DateTime.Now; // 更新支付时间

                _dbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                // 记录错误日志
                Console.WriteLine($"更新订单状态失败: {ex.Message}");
                throw;
            }
        }
        private async Task<bool> OrderAlreadyProcessedAsync(string orderId)
        {
            try
            {
                var order = await _dbContext.Orders.FirstOrDefaultAsync(o => o.OrderID == orderId);

                if (order == null)
                {
                    return false;
                }

                return order.Status == (OrderStatus)2;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查订单是否已处理时出错: {ex.Message}");
                throw;
            }
        }

        private async Task UpdateOrderStatusAsync(string orderId)
        {
            try
            {
                var order = await _dbContext.Orders.FirstOrDefaultAsync(o => o.OrderID == orderId);

                if (order == null)
                {
                    throw new Exception($"订单 ID: {orderId} 不存在");
                }

                order.Status = (OrderStatus)2;
                order.PaidAt = DateTime.Now;

                await _dbContext.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"更新订单状态失败: {ex.Message}");
                throw;
            }
        }
    }

    public class OrderRequest
    {
        public string OrderId { get; set; } // 订单号
        public decimal Amount { get; set; } // 金额（元）
        public string Description { get; set; } // 商品描述
        public string OpenId { get; set; } // 用户的 OpenId
    }
}
